home *** CD-ROM | disk | FTP | other *** search
/ Risc World 5 / Risc World 5.iso / SOFTWARE / Issue5 / PD / DIRSYNC / LegalStuff / ccres / c / Eval < prev    next >
Text File  |  2004-03-20  |  3KB  |  142 lines

  1. /* Eval.c
  2.    $Id: Eval.c,v 1.2 2004/03/20 22:12:22 joty Exp $
  3.  
  4.    Copyright (c) 2003-2004 Dave Appleby / John Tytgat
  5.  
  6.    This file is part of CCres.
  7.  
  8.    CCres is free software; you can redistribute it and/or modify
  9.    it under the terms of the GNU General Public License as published by
  10.    the Free Software Foundation; either version 2 of the License, or
  11.    (at your option) any later version.
  12.  
  13.    CCres is distributed in the hope that it will be useful,
  14.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.    GNU General Public License for more details.
  17.  
  18.    You should have received a copy of the GNU General Public License
  19.    along with CCres; if not, write to the Free Software
  20.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  21.  */
  22.  
  23. #include "ccres.h"
  24.  
  25. #include <ctype.h>
  26.  
  27. // hi nybble = precedence, added to lo nybble to make unique id
  28. enum {LBRACKET=0x11,ADD=0x21,SUB=0x22,MUL=0x31,DIV=0x32};
  29. #define Precedence(op) ((op)&0xf0)
  30.  
  31. static BOOL Eval2(PINT sop, PINT sn, PINT piop, PINT pin)
  32. {
  33.     int lnum, op, rnum;
  34.     int iop, in, res;
  35.  
  36.     iop = *piop;
  37.     in = *pin;
  38.  
  39.     rnum = sn[--in];
  40.     lnum = sn[--in];
  41.     op = sop[--iop];
  42.     if (op == MUL) {
  43.         res = lnum * rnum;
  44.     } else if (op ==  DIV) {
  45.         if (rnum == 0) {
  46.             return(FALSE);
  47.         } else {
  48.             res = lnum / rnum;
  49.         }
  50.     } else if (op ==  ADD) {
  51.         res = lnum + rnum;
  52.     } else if (op ==  SUB) {
  53.         res = lnum - rnum;
  54.     } else {
  55.         return(FALSE);
  56.     }
  57.     sn[in++] = res;
  58.  
  59.     *piop = iop;
  60.     *pin = in;
  61.     return(TRUE);
  62. }
  63.  
  64.  
  65. int Eval(PDATA data, PSTR * ppstr)
  66. {
  67.     PSTR pstr;
  68.     int sop[16], sn[16];
  69.     int iop, in, op;
  70.     BOOL fOp;
  71.     char ch;
  72.  
  73.     pstr = *ppstr;
  74.     iop = in = 0;
  75.     fOp = TRUE;
  76.     for (;;) {
  77.         if ((ch = *pstr++) == ' ' || ch == '\t' ) {
  78.             // do nothing
  79.         } else if (ch == '(') {
  80.             if (iop >= ELEMENTS(sop)) {
  81.                 goto Eval_SyntaxError;
  82.             }
  83.             sop[iop++] = LBRACKET;
  84.             fOp = TRUE;
  85.         } else if (ch == ')') {
  86.             if (iop == 0) {
  87.                 goto Eval_SyntaxError;
  88.             } else {
  89.                 while (sop[iop - 1] != LBRACKET) {
  90.                     if (!Eval2(sop, sn, &iop, &in)) {
  91.                         goto Eval_SyntaxError;
  92.                     }
  93.                 }
  94.                 iop--;        // pop LBRACKET
  95.             }
  96.             fOp = FALSE;
  97.         } else if ((ch == '-' && !fOp) || ch == '+' || ch == '/' || ch == '*') {
  98.             op = (ch == '+') ? ADD :
  99.                  (ch == '-') ? SUB :
  100.                  (ch == '*') ? MUL : DIV;
  101.             while (iop > 0 && Precedence(sop[iop - 1]) >= Precedence(op)) {
  102.                 if (!Eval2(sop, sn, &iop, &in)) {
  103.                     goto Eval_SyntaxError;
  104.                 }
  105.             }
  106.             if (iop >= ELEMENTS(sop)) {
  107.                 goto Eval_SyntaxError;
  108.             }
  109.             sop[iop++] = op;
  110.             fOp = TRUE;
  111.         } else if (isdigit(ch) || (ch == '-' && fOp) || ch == '&') {
  112.             if (in >= ELEMENTS(sn)) {
  113.                 goto Eval_SyntaxError;
  114.             }
  115.             pstr--;
  116. //LOG(("__atoi(%s)", pstr));
  117.             sn[in++] = __atoi(&pstr);
  118. //LOG(("val=%d New pstr = %s", sn[in - 1], pstr));
  119.             fOp = FALSE;
  120.         } else {
  121.             pstr--;
  122.             break;
  123.         }
  124.     }
  125.     while (iop > 0) {
  126.         if (!Eval2(sop, sn, &iop, &in)) {
  127.             goto Eval_SyntaxError;
  128.         }
  129.     }
  130.     if (in == 1) {
  131.         *ppstr = pstr;
  132.         return(sn[0]);
  133.     }
  134.  
  135. Eval_SyntaxError:
  136.  
  137. LOG(("Expression syntax error"));
  138.     report(data, *ppstr, "Expression syntax error");
  139.     *ppstr = pstr;
  140.     return(0);
  141. }
  142.